package com.deepcode.StringProcess.struct;

import com.deepcode.StringProcess.domain.CharObject;

/**
 * linked list management
 */
public class CharLinkedList {
    private CharObject head;
    private CharObject tail;
    private int size;

    public CharLinkedList() {
        this.head = null;
        this.tail = null;
        this.size = 0;
    }

    /**
     * 从字符串创建双向链表
     *
     * @param str 输入字符串
     */
    public void fromString(String str) {
        if (str == null || str.isEmpty()) {
            return;
        }

        clear();

        for (char ch : str.toCharArray()) {
            append(ch);
        }
    }

    /**
     * 在链表末尾添加字符
     *
     * @param ch 字符
     */
    public void append(char ch) {
        CharObject newNode = new CharObject(ch);

        if (head == null) {
            head = tail = newNode;
        } else {
            newNode.setPrev(tail);
            tail.setNext(newNode);
            tail = newNode;
        }
        size++;
    }

    /**
     * 删除指定节点
     *
     * @param node 要删除的节点
     */
    public void remove(CharObject node) {
        if (node == null) return;

        if (node.getPrev() != null) {
            node.getPrev().setNext(node.getNext());
        } else {
            head = node.getNext();
        }

        if (node.getNext() != null) {
            node.getNext().setPrev(node.getPrev());
        } else {
            tail = node.getPrev();
        }
        if (size > 0) {
            size--;
        }

    }

    /**
     * 在指定节点前插入字符
     *
     * @param node 指定节点
     * @param ch   要插入的字符
     */
    public void insertBefore(CharObject node, char ch) {
        if (node == null) return;

        CharObject newNode = new CharObject(ch);
        newNode.setNext(node);
        newNode.setPrev(node.getPrev());

        if (node.getPrev() != null) {
            node.getPrev().setNext(newNode);
        } else {
            head = newNode;
        }

        node.setPrev(newNode);
        size++;
    }

    /**
     * 将链表转换为字符串
     *
     * @return 字符串表示
     */
    public String toString() {
        StringBuilder sb = new StringBuilder();
        CharObject current = head;

        while (current != null) {
            sb.append(current.getCharacter());
            current = current.getNext();
        }

        return sb.toString();
    }

    /**
     * 获取头节点
     *
     * @return 头节点
     */
    public CharObject getHead() {
        return head;
    }

    /**
     * 清空链表
     */
    public void clear() {
        head = null;
        tail = null;
        size = 0;
    }

    /**
     * 获取链表大小
     *
     * @return 链表大小
     */
    public int getSize() {
        return size;
    }
}